# gozerlib/wave/bot.py
#
#

""" google wave bot. """

## gozerlib imports

from gozerlib.persist.persist import Persist
from gozerlib.botbase import BotBase
from gozerlib.plugins import plugs
from gozerlib.utils.generic import getversion
from gozerlib.utils.auth import finduser
from event import WaveEvent
from waves import Wave

## waveapi imports

from waveapi import events
from waveapi import model
from waveapi import robot
from waveapi import document
from waveapi import robot_abstract

## generic imports

import logging
import cgi
import os

waves = {}

class WaveBot(BotBase, robot.Robot):

    """ 
        bot to implement google wave stuff. 

        :param name: bot's name
        :type param: string
        :param image_url: url pointing to the bots image
        :type image_url: string
        :param version: the bots version 
        :type version: string
        :param profile_url: url pointing to the bots profile
        :type profile_url: string

    """

    def __init__(self, name='gozertest', 
                 image_url='http://gozerwave.appspot.com/assets/icon.png',
                 version='8',
                 profile_url='http://gozerwave.appspot.com/'):
        BotBase.__init__(self, name)
        robot.Robot.__init__(self, name=name, version=version, image_url=image_url, profile_url=profile_url)
        self.RegisterHandler(events.BLIP_SUBMITTED, self.OnBlipSubmitted)
        self.RegisterHandler(events.WAVELET_PARTICIPANTS_CHANGED, self.OnParticipantsChanged)
        self.RegisterHandler(events.WAVELET_SELF_ADDED, self.OnRobotAdded)
        self.type = "wave"
        self.iswave = True
        self.channels = Persist("gozerstore" + os.sep + "fleet" + os.sep + self.name + os.sep + "channels")
        self.waves = waves
 
    def OnParticipantsChanged(self, properties, context):

        """ invoked when any participants have been added/removed. """

        pass

    def OnRobotAdded(self, properties, context):

        """ invoked when the robot has been added. """

        root_wavelet = context.GetRootWavelet()
        root_wavelet.CreateBlip().GetDocument().AppendText(getversion('WAVE'))
        root_wavelet.CreateBlip().GetDocument().AppendText('see !help')
        #blip = context.GetBlipById(properties['blipId'])
        #blip.CreateChild().GetDocument().SetText(getversion('WAVE'))
        #blip.CreateChild().GetDocument().SetText(' .. see !help')
        waveid = root_wavelet.waveId
        #waveid = properties['blipId']
        self.waves[waveid] = Wave(waveid).parse(properties, context)
        logging.info('joined "%s" (%s) wave' % (waveid, root_wavelet.title))

    def OnBlipSubmitted(self, properties, context):

        """ new blip added. here is where the command dispatching takes place. """

        event = WaveEvent().parse(self, properties, context)
        root_wavelet = context.GetRootWavelet()
        #waveid = properties['blipId']
        #blip = context.GetBlipById(properties['blipId'])
        waveid = root_wavelet.waveId
        self.waves[waveid] = Wave(waveid).parse(properties, context)
        logging.debug("added %s (%s) to the waves list" % (waveid, root_wavelet.title))

        #rootid = root_wavelet.GetId()

        if len(event.txt) >= 2 and event.txt[0] == '!':
            event.txt = event.txt[1:]
            event.auth = event.userhost
            plugs.dispatch(self, event)

    def say(self, waveid, txt):

        """
            output to the root id. 

            :param waveid: id of the wave 
            :type waveid: string
            :param txt: text to output
            :type txt: string
            :rtype: None

        """

        try:
            wave = self.waves[waveid]
        except KeyError:
            logging.debug("no wave found for %s" % waveid)
            return

        if wave:
            wave.say(txt)

    def newwave(self, context):

        """
            create a new wave. 

        """

        newwave = robot_abstract.NewWave(context)
        logging.debug('newwave: %s' % dir(newwave))
        return newwave
